package models

import (
	"encoding/json"
	"errors"
	"log"
	"reflect"

	"jlpay-sdk-go/pkg/jlpay/core"
)

// OrgBaseRequest 机构请求基类
type OrgBaseRequest struct {
	// OrgNo 机构号
	OrgNo string `json:"org_no,omitempty"`
	// MerchNo 商户号
	MerchNo string `json:"merch_no,omitempty"`
	// 敏感字段列表（不序列化）
	sensitiveFields []string `json:"-"`
}

// RawMapGetter 原始请求映射获取接口
type RawMapGetter interface {
	// GetRawMap 获取原始请求映射数据
	GetRawMap() (map[string]interface{}, bool)
}

// SetOrgNo 设置机构号
func (r *OrgBaseRequest) SetOrgNo(orgNo string) *OrgBaseRequest {
	r.OrgNo = orgNo
	return r
}

// SetMerchNo 设置商户号
func (r *OrgBaseRequest) SetMerchNo(merchNo string) *OrgBaseRequest {
	r.MerchNo = merchNo
	return r
}

// AddSensitiveField 添加敏感字段
func (r *OrgBaseRequest) AddSensitiveField(fieldName string) *OrgBaseRequest {
	if r.sensitiveFields == nil {
		r.sensitiveFields = make([]string, 0, 8)
	}
	for _, field := range r.sensitiveFields {
		if field == fieldName {
			return r
		}
	}
	r.sensitiveFields = append(r.sensitiveFields, fieldName)
	return r
}

// GetSensitiveFields 获取敏感字段列表
func (r *OrgBaseRequest) GetSensitiveFields() []string {
	return r.sensitiveFields
}

// CheckRequiredParams 检查必需参数
func (r *OrgBaseRequest) CheckRequiredParams(config *core.Config) error {
	// 已移除机构号和商户号的非空校验
	return nil
}

// ToMap 将请求转换为map，过滤掉值为nil的字段
func (r *OrgBaseRequest) ToMap() (map[string]interface{}, error) {
	data, err := json.Marshal(r)
	if err != nil {
		return nil, err
	}

	var result map[string]interface{}
	if err := json.Unmarshal(data, &result); err != nil {
		return nil, err
	}

	// 过滤掉值为nil的字段
	for key, value := range result {
		if isNilOrEmpty(value) {
			delete(result, key)
		}
	}

	return result, nil
}

// isNilOrEmpty 判断值是否为nil或空
func isNilOrEmpty(v interface{}) bool {
	if v == nil {
		return true
	}

	value := reflect.ValueOf(v)
	kind := value.Kind()

	switch kind {
	case reflect.String:
		return value.String() == ""
	case reflect.Slice, reflect.Map:
		return value.Len() == 0
	case reflect.Ptr:
		return value.IsNil()
	default:
		return false
	}
}

// BaseResponse 响应基类接口
type BaseResponse interface {
	// IsSuccess 是否成功
	IsSuccess() bool
	// GetRetCode 获取返回码
	GetRetCode() string
	// GetRetMsg 获取返回信息
	GetRetMsg() string
	// GetOriginData 获取原始响应数据
	GetOriginData() map[string]interface{}
	// HandleResponse 处理响应并打印结果
	HandleResponse(operationName string)
}

// StandardResponse 标准响应实现
type StandardResponse struct {
	// RetCode 返回码，00000表示成功
	RetCode string `json:"ret_code"`
	// RetMsg 返回信息
	RetMsg string `json:"ret_msg"`
	// 原始响应数据
	originData map[string]interface{} `json:"-"`
}

// IsSuccess 是否成功
func (r *StandardResponse) IsSuccess() bool {
	return r.RetCode == "00000" || r.RetCode == "00"
}

// GetRetCode 获取返回码
func (r *StandardResponse) GetRetCode() string {
	return r.RetCode
}

// GetRetMsg 获取返回信息
func (r *StandardResponse) GetRetMsg() string {
	return r.RetMsg
}

// GetOriginData 获取原始响应数据
func (r *StandardResponse) GetOriginData() map[string]interface{} {
	return r.originData
}

// SetOriginData 设置原始响应数据
func (r *StandardResponse) SetOriginData(data map[string]interface{}) {
	r.originData = data
}

// HandleResponse 处理响应并打印结果
func (r *StandardResponse) HandleResponse(operationName string) {
	if r.IsSuccess() {
		log.Printf("%s成功！", operationName)
		// 打印原始响应报文
		originData := r.GetOriginData()
		if originData != nil {
			originJSON, _ := json.MarshalIndent(originData, "", "  ")
			log.Printf("响应报文：\n%s", string(originJSON))
		}
	} else {
		log.Printf("%s失败: %s - %s", operationName, r.GetRetCode(), r.GetRetMsg())
		// 即使失败也打印响应报文
		originData := r.GetOriginData()
		if originData != nil {
			responseJSON, _ := json.MarshalIndent(originData, "", "  ")
			log.Printf("响应报文：\n%s", string(responseJSON))
		}
	}
}

// NewBaseResponse 创建新的响应
func NewBaseResponse(data map[string]interface{}) BaseResponse {
	resp := &StandardResponse{
		originData: data,
	}
	if code, ok := data["ret_code"].(string); ok {
		resp.RetCode = code
	}
	if msg, ok := data["ret_msg"].(string); ok {
		resp.RetMsg = msg
	}
	return resp
}

// ParseResponse 解析响应
func ParseResponse(data map[string]interface{}, response interface{}) error {
	// 先将map转换为JSON字符串
	jsonData, err := json.Marshal(data)
	if err != nil {
		return errors.New("序列化响应数据失败: " + err.Error())
	}

	// 再将JSON字符串解析为结构体
	if err := json.Unmarshal(jsonData, response); err != nil {
		return errors.New("解析响应数据失败: " + err.Error())
	}

	// 如果响应实现了设置原始数据的接口，则调用该接口
	if setter, ok := response.(interface{ SetOriginData(map[string]interface{}) }); ok {
		setter.SetOriginData(data)
	}

	return nil
}
